package com.hmdp.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.hmdp.entity.VoucherOrder;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class SaveSeckillRequestToBackup {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // mq消息兜底存储：Redis List + 本地文件
    public void saveSeckillRequestToRedis(Long orderId, VoucherOrder voucherOrder) {
        // 1. 写入Redis临时队列（高性能，便于后续补发）
        String backupKey = "seckill:mq:backup";
        String orderJson = JSONUtil.toJsonStr(voucherOrder);
        try {
            // LPUSH写入，设置7天过期（覆盖秒杀活动周期）
            stringRedisTemplate.opsForList().leftPush(backupKey, orderJson);
            stringRedisTemplate.expire(backupKey, 7, TimeUnit.DAYS);
            log.info("订单{}已写入Redis兜底队列", orderId);
        } catch (Exception e) {
            log.error("订单{}写入Redis兜底失败", orderId, e);
            // Redis写入失败，降级到本地文件
            saveToLocalFile(orderId, voucherOrder);
        }
    }

    // mq本地文件兜底（最后一道防线）
    private void saveToLocalFile(Long orderId, VoucherOrder voucherOrder) {
        // 按日期分片存储，避免单个文件过大
        String dateDir = DateUtil.today();
        String fileName = String.format("seckill_backup_%s.log", dateDir);
        String filePath = String.format("/data/seckill/backup/%s", fileName);

        // 确保目录存在
        File dir = new File("/data/seckill/backup/");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 追加写入文件（BufferedWriter提升性能）
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
            String orderJson = JSONUtil.toJsonStr(voucherOrder);
            writer.write(orderJson);
            writer.newLine();
            log.info("订单{}已写入本地兜底文件：{}", orderId, filePath);
        } catch (IOException e) {
            log.error("订单{}写入本地文件失败", orderId, e);
            // 触发告警：钉钉/企业微信通知运维
            sendAlarm("秒杀订单" + orderId + "本地兜底失败，可能丢失！");
        }
    }

    private void sendAlarm(String alarmMsg) {
        // 1. 先打印错误日志（必做）
        log.error("秒杀系统告警：{}", alarmMsg);
    }

}
